分布式

您所在的位置:网站首页 分布式数据库中间件对比总结mycat cobar sharding 分布式

分布式

2024-01-07 01:09| 来源: 网络整理| 查看: 265

不啰嗦,我们直接开始!

1、面试官:说一说你项目里为什么要分库分表?在什么情况下会使用分库分表。

问题分析:数据库中的数据量不一定是可控的,在未进行分库分表的情况下,随着时间和业务的发展,库中的表会越来越多,表中的数据也会越来越多,表中的数据量也会越来越大,相应地,数据操作,增删改查的开销也会越来越大,根据个人经验,单表数据在1000w以后,你就要提前规划下后事了,是解决问题还是辞职跑路?所以这一块是分布式系统面试中必问的。

答:一句话概括就是为了提高数据库的读写的效率,更重要的是提高读效率,提高查询的性能,解决数据量过大从而导致的数据库性能下降的问题,如果业务数据日增量比较大,那么就要提前预估,现有单库单表的数据量读写速度能支撑多久,提前规划时间改造。

举个例子说明,比如用户信息表中现在有3000w条用户数据,此时我们需要在这个表中 insert 一条新的数据,insert 完毕后,数据库会针对用户表重新建立索引,3000w 行数据建立索引的系统开销还是不容忽视的。

假如我们将这个大表分成3个分表,从user_0,user_1,user_2,3000w行数据平均分3张表,每个子表里有1000w行数据,对1000w行的表中insert数据,建立索引的时间就会下降,从而提高了DB的运行时效率,进而提高并发量。

当然分表的好处还不止这些,还有诸如减少写操作时锁范围等,都会带来很多明显的优点。

分库: 提高架构可用性,减少单点故障,有效分担一个库的压力,只分库不分表,常用于读写分离场景,一主多从,主库负责写,从库用于读,从库从主库同步更新数据,保持数据一致,适用于写入少读取多的场景。分表: 把数据分片拆分,多个表数据减少,insert 插入速度提高,读取速度也得以提高。

我的内心:这个问题是不是有点简单呀,这么基础的概念问题。

2、面试官:嗯,你继续,你是怎么做分库分表的?

问题分析: ok,这个问题依旧不难,开始我本想从垂直切分/水平切分这个问题来讲解,后来想想太概念化没意思,直接用每个系统都会有的user表举例,自己理解吧。

答:还拿用户信息表举例:

不分库只分表: 将db库中的user表拆分为3个分表,user_0,user_1,user_2,每个子表里有1000w行数据,这3个表还位于同一个库中,属于水平切分。

图片描述

只分库不分表: 将db库拆分为db_0,db_1,db_2 三个库,同时在db_0,db_1,db_2 库中各自新建一个user表,db_0.user,db_1.user,db_2.user 表中各自只存原来的db.user表中的部分数据,每个子里有1000w行数据。

图片描述

既分库又分表: 将db库拆分为db_0,db_1,db_2 三个库,db_0中包含user_0、user_1两个分表,db_1中包含user_2、user_3两个分表,db_2里有user_4,user_5。这样每张表里有500w行数据。

图片描述

 3、面试官:你是使用什么策略做的分库分表?或者说,根据什么算法拆分数据。

 问题分析: 前两个问题我还对答如流,这个问题也ok,我用的取模法呀。

答:

对key取模法: 项目中我主要是用的这个方法给user表做的分表。 如采用第三种即分库又分表方法为例,根据userId把3000w最终分6张表,n = 6,userId = 10001 取模(10001% 6 = 5)这条数据落在db_2 第user_4分片上,10002 % 6 = 0,落在db_0 第user_0个分片上,以此类推,(注意:分片数从0计数),可以哈希后再取模,Hash(userId)% n ,此种方法数据分布较均匀。

RANGE分区:

这个是我额外了解的方法,userId 从0 - 500w一张表,5000001 - 1000w一张表,依此类推。目前没有在项目中使用过此方法,我觉得这个方法在增量表场景中会造成数据分布不均匀,没道理是用此方法。

时间分区: 这个方法很实用,适用于订单数据拆分,如按天分表,按月分表,按年分表,时间越久的数据被查询的概率就会越低,类似冷热数据分离,比如我用ES给订单数据做归档,就是使用的按月索引。

 到这里我已经我说得很全面了,至少点到了,那么问题来了

面试官: 刚刚你说user表你使用的是对key取模法,比如你2019年用户量 3000w, n = 6可以保证两年增长量不用再拆分,如果业务突飞猛进,到2020年就变两亿用户了, n = 6显然不够,这个时候对key取模法会有什么问题吗?

我陷入了深深的思考…

当时的我被问住了,关于这个问题,我回来后查阅资料总结了一下:

对key取模法有一个缺点:如果n变大,比如现在要把分片数调整为 n=12,那么之前已经计算好的取模值会变,那已经存在的3000w数据是不是要重新分片了?答案是会的,你将要面临大量额外的数据迁移工作,如果这个n变动频繁,是不是考虑还有更好的解决办法,答案就是一致性hash算法,这个算法触及了我的知识盲区,这个算法复杂,可以参考一致性Hash算法及使用场景进一步了解。

关于这个问题,我并不觉得这个算法是更好的,对key取模法没有问题,如果你能估算好数据增量,合理地做好规划,比如5年后需要重刷数据,那5年一次重构也没什么不妥,那个时候你去哪里了都不知道,这个问题只能说明我在了解一个新事物后并没有从更多维度去考虑这个问题,这也是面试官指出的问题所在。

深入分析

 这里还有个比较重要的问题面试官没问,就是分库分表,分多少个库比较合适,分多少个表合适,有经验可循吗?

这是我在公司DBA那里得到的经验值,补上,下次面试可以跟面试官多掰扯一下。

 表数目决策: 一般情况下,建议单个物理分表的容量不超过1000万行数据。通常可以预估2到5年的数据增长量,用估算出的总数据量除以总的物理分库数,再除以建议的最大数据量1000万,即可得出每个物理分库上需要创建的物理分表数。

库数目决策: 计算公式:按照存储容量来计算 = (3到5年内的存储容量)/ 单个库建议存储容量 (单个库建议存储容量



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3